package com.dy.yunying.biz.service.datacenter.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dy.yunying.api.datacenter.dto.AdOverviewDto2;
import com.dy.yunying.api.datacenter.vo.AdDataAnalysisVO;
import com.dy.yunying.api.entity.ChannelManageDO;
import com.dy.yunying.api.entity.ParentGameDO;
import com.dy.yunying.api.entity.WanGameChannelInfoDO;
import com.dy.yunying.api.entity.WanGameDO;
import com.dy.yunying.biz.dao.datacenter.impl.AdAnalysisDao;
import com.dy.yunying.biz.dao.manage.ChannelManageDOMapper;
import com.dy.yunying.biz.dao.manage.ParentGameDOMapper;
import com.dy.yunying.biz.dao.manage.WanGameChannelInfoMapper;
import com.dy.yunying.biz.dao.manage.WanGameDOMapper;
import com.dy.yunying.biz.service.datacenter.AdAnalysisService;
import com.dy.yunying.biz.service.manage.AdRoleUserService;
import com.dy.yunying.biz.utils.AdPlanUtil;
import com.google.api.client.util.Lists;
import com.pig4cloud.pig.api.entity.AdAccount;
import com.pig4cloud.pig.api.feign.RemoteAccountService;
import com.pig4cloud.pig.api.vo.AdAccountVo;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.service.PigUser;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 广告数据分析表相关方法
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AdAnalysisServiceImpl implements AdAnalysisService {

	private final AdRoleUserService adRoleUserService;

	private final RemoteAccountService remoteAccountService;

	private final AdAnalysisDao adAnalysisDao;

	private final ChannelManageDOMapper channelManageDOMapper;

	private final WanGameChannelInfoMapper wanGameChannelInfoMapper;

	private final ParentGameDOMapper parentGameDOMapper;

	private final WanGameDOMapper wanGameDOMapper;

	/**
	 * 广告数据分析表总数查询
	 *
	 * @param req
	 * @return
	 */
	@Override
	public R count(AdOverviewDto2 req) {
		Long count;
		try {
			this.managerParam(req);

			count = adAnalysisDao.countDataTotal(req);
		} catch (Exception e) {
			log.error("countDataTotal:[{}]", e);
			return R.failed("广告数据分析报表总记录数查询失败");
		}
		return R.ok(count);
	}

	/**
	 * 广告数据分析表分页列表查询
	 *
	 * @param req
	 * @return
	 */
	@Override
	public R<List<AdDataAnalysisVO>> page(AdOverviewDto2 req) {
		this.managerParam(req);

		List<AdDataAnalysisVO> adPlanOverviewVoList = adAnalysisDao.list(req); // 查询数据
		this.deal(adPlanOverviewVoList, req);
		return R.ok(adPlanOverviewVoList);
	}

	private void managerParam(AdOverviewDto2 req){
		// 判断是否管理员
		if (SecurityUtils.getRoles().contains(1)) {
			req.setIsSys(1);
		} else {
			// 当前用户
			final PigUser user = SecurityUtils.getUser();
			List<Integer> ownerRoleUserIds = adRoleUserService.getOwnerRoleUserIds();
			// 当前账号及管理的账号
			List<Integer> roleUserIdList = new ArrayList<>();
			req.setRoleUserIdList(roleUserIdList);
			roleUserIdList.add(user.getId());
			if (CollectionUtils.isNotEmpty(ownerRoleUserIds)) {
				roleUserIdList.addAll(ownerRoleUserIds);
			}

			// 授权的广告账户
			List<String> roleAdAccountList = new ArrayList<>();
			req.setRoleAdAccountList(roleAdAccountList);
			//查询角色用户对应的广告账号
			final List<String> accountList2 = adRoleUserService.getThrowAccountList();
			if (ObjectUtils.isNotEmpty(accountList2)) {
				roleAdAccountList.addAll(accountList2);
			}
		}
	}

	private void deal(List<AdDataAnalysisVO> list, AdOverviewDto2 req) {
		if (CollectionUtils.isEmpty(list)) {
			return;
		}

		// 填充主渠道名称
		if (StringUtils.contains(req.getQueryColumn(), "parentchl")) {
			final List<String> codeList = list.stream().map(AdDataAnalysisVO::getParentchl).distinct().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
			final Map<String, String> mapping = codeList.isEmpty() ? Collections.emptyMap() : channelManageDOMapper.selectList(Wrappers.<ChannelManageDO>lambdaQuery().select(ChannelManageDO::getChncode, ChannelManageDO::getChnname).in(ChannelManageDO::getChncode, codeList).eq(ChannelManageDO::getPid, 0)).stream().collect(Collectors.toMap(ChannelManageDO::getChncode, ChannelManageDO::getChnname, (k1, k2) -> k1));
			list.forEach(e -> e.setParentchlname(StringUtils.defaultIfBlank(mapping.get(e.getParentchl()), "-")));
		}
		// 填充主分包渠道名称
		if (StringUtils.contains(req.getQueryColumn(), "appchl")) {
			final List<String> codeList = list.stream().map(AdDataAnalysisVO::getAppchl).distinct().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
			final Map<String, String> mapping = codeList.isEmpty() ? Collections.emptyMap() : wanGameChannelInfoMapper.selectList(Wrappers.<WanGameChannelInfoDO>lambdaQuery()
					.select(WanGameChannelInfoDO::getChl, WanGameChannelInfoDO::getCodeName)
					.in(WanGameChannelInfoDO::getChl, codeList))
					//codeName 存在 null 值会导致NPE
					.stream().collect(HashMap::new, (m, v) -> m.put(v.getChl(), v.getCodeName()), HashMap::putAll);

			list.forEach(e -> e.setAppchl(StringUtils.defaultIfBlank(mapping.getOrDefault(e.getAppchl(), e.getAppchl()), "-")));
		}
		// 填充主游戏名称
		if (StringUtils.contains(req.getQueryColumn(), "pgid")) {
			final List<Long> codeList = list.stream().map(AdDataAnalysisVO::getPgid).distinct().filter(Objects::nonNull).collect(Collectors.toList());
			final Map<Long, String> mapping = codeList.isEmpty() ? Collections.emptyMap() : parentGameDOMapper.selectList(Wrappers.<ParentGameDO>lambdaQuery().select(ParentGameDO::getId, ParentGameDO::getGname).in(ParentGameDO::getId, codeList)).stream().collect(Collectors.toMap(ParentGameDO::getId, ParentGameDO::getGname, (k1, k2) -> k1));
			list.forEach(e -> e.setParentGameName(StringUtils.defaultIfBlank(mapping.get(e.getPgid()), "-")));
		}
		// 填充子游戏名称
		if (StringUtils.contains(req.getQueryColumn(), "gameid")) {
			final List<Long> codeList = list.stream().map(AdDataAnalysisVO::getGameid).distinct().filter(Objects::nonNull).collect(Collectors.toList());
			final Map<Long, String> mapping = codeList.isEmpty() ? Collections.emptyMap() : wanGameDOMapper.selectList(Wrappers.<WanGameDO>lambdaQuery().select(WanGameDO::getId, WanGameDO::getGname).in(WanGameDO::getId, codeList)).stream().collect(Collectors.toMap(WanGameDO::getId, WanGameDO::getGname, (k1, k2) -> k1));
			list.forEach(e -> e.setGameName(StringUtils.defaultIfBlank(mapping.get(e.getGameid()), "-")));
		}

		// 填充计划相关字段
		if (StringUtils.contains(req.getQueryColumn(), "adid")) {
			for (AdDataAnalysisVO data : list) {
				if (StringUtils.isNotBlank(data.getStartTime())) {
					String schduleType = data.getStartTime() + "至" + (StringUtils.isNotBlank(data.getEndTime()) ? data.getEndTime() : "不限");
					data.setScheduleType(schduleType);
				}
				final int ctype = Integer.parseInt(req.getPlatformType());
				data.setStatus(AdPlanUtil.getStatusEnumValue(data.getStatus(), ctype, "-"));
				data.setUnionVideoType(AdPlanUtil.getUnionVideoEnumValue(data.getUnionVideoType(), ctype, "-"));
				data.setDeliveryRange(AdPlanUtil.getDeliveryRangeEnumValue(data.getDeliveryRange(), ctype, "-"));
				final String inventoryType = StringUtils.defaultIfBlank(data.getInventoryType(), "[]");
				data.setInventoryType(JSON.parseArray(inventoryType, String.class).stream().map(e -> AdPlanUtil.getInventoryTypeEnumValue(e, ctype, "-")).collect(Collectors.toList()).toString());
				final String convertDescri = this.getConvertDescri(data, ctype);
				data.setConvertDescri(convertDescri);

				if (req.getCycleType() != null && StringUtils.isBlank(data.getAdid())) {
					data.setAdidName("自然量");
				}
			}
		}

		// 填充广告账户相关字段
		if (StringUtils.contains(req.getQueryColumn(), "advertiserid")) {
			final List<String> codeList = list.stream().map(AdDataAnalysisVO::getAdvertid).distinct().filter(Objects::nonNull).collect(Collectors.toList());
			final Map<String, String> mapping = codeList.isEmpty() ? Collections.emptyMap() :
					Optional.ofNullable(remoteAccountService.getAllList(new AdAccountVo().setAdvertiserIds(codeList), SecurityConstants.FROM_IN))
							.orElse(Collections.emptyList())
							.stream().filter(e -> StringUtils.isNotBlank(e.getAdvertiserName()))
							.collect(Collectors.toMap(AdAccount::getAdvertiserId, AdAccount::getAdvertiserName, (k1, k2) -> k1));
			for (AdDataAnalysisVO data : list) {
				data.setAdAccountName(StringUtils.defaultIfBlank(mapping.get(data.getAdvertid()), "-"));
				if (req.getCycleType() != null && StringUtils.isBlank(data.getAdvertid())) {
					data.setAdAccountName("自然量");
				}
			}
		}

		// 填充转化目标相关字段
		if (StringUtils.contains(req.getQueryColumn(), "convertName")) {
			for (AdDataAnalysisVO data : list) {
				final int ctype = Integer.parseInt(req.getPlatformType());
				final String convertDescri = this.getConvertDescri(data, ctype);
				data.setConvertDescri(convertDescri);
				if (req.getCycleType() != null && StringUtils.isBlank(data.getConvertName())) {
					data.setConvertDescri("自然量");
				}
			}
		}

	}

	private String getConvertDescri(AdDataAnalysisVO data, int ctype) {
		final String convertName = data.getConvertName();
		String convertTargetEnumValue = AdPlanUtil.getConvertTargetEnumValue(convertName, ctype, null);
		String deepConvertEnumValue = AdPlanUtil.getDeepConvertEnumValue(data.getDeepConvert(), ctype, null);
		if (StringUtils.isNotBlank(deepConvertEnumValue)) {
			return convertTargetEnumValue + '-' + deepConvertEnumValue;
		} else if ("AD_CONVERT_TYPE_ACTIVE".equals(convertName) || "AD_CONVERT_TYPE_PAY".equals(convertName)) {
			return convertTargetEnumValue + "-无";
		} else {
			return convertTargetEnumValue;
		}
	}

}
